let ui_btnCameraPriview = document.getElementById("btnCameraPriview") as HTMLButtonElement;
let ui_btnRefreshCameraList = document.getElementById("btnRefreshCameraList") as HTMLButtonElement;
let ui_btnRefreshShotStatus = document.getElementById("btnRefreshShotStatus") as HTMLButtonElement;
let ui_btnStartShot = document.getElementById("btnStartShot") as HTMLButtonElement;
let ui_btnStopShot = document.getElementById("btnStopShot") as HTMLButtonElement;
let ui_btnGetSettingList = document.getElementById("btnGetSettingList") as HTMLButtonElement;
let ui_btnGetSettingValue = document.getElementById("btnGetSettingValue") as HTMLButtonElement;
let ui_formSettingList = document.getElementById("formSettingList") as HTMLFormElement;

ui_btnRefreshShotStatus.addEventListener("click", click_RefreshShotStatus);
ui_btnRefreshCameraList.addEventListener("click", click_GetDeviceList);
ui_btnStartShot.addEventListener("click", click_StartShot);
ui_btnStopShot.addEventListener("click", click_StopShot);
ui_btnGetSettingList.addEventListener("click", click_GetSettingList);
ui_btnGetSettingValue.addEventListener("click", click_GetSettingValue);

function GetSelectCamera(): string | null {
  let ui_Select = document.getElementById("selectCamera") as HTMLSelectElement;
  if (ui_Select == null)
    return null;
  return ui_Select.value;
}

function SetLog(msg: string): void {
  let text = document.getElementById("labLogInfo") as HTMLElement;
  text.innerText = msg;
}

function click_RefreshShotStatus() {
  interface retShotStatus {
    value: boolean;
  }
  let callbackend = new XMLHttpRequest();
  callbackend.onreadystatechange = () => {
    if (callbackend.readyState == 4) {
      if (callbackend.status == 200) {
        let RetObj: retShotStatus = JSON.parse(callbackend.response);
        let ui_ShotStauts = document.getElementById("labShotStatus");
        if (ui_ShotStauts != null)
          ui_ShotStauts.innerText = String(RetObj.value);
      }
      else
        SetLog("Call RefreshShotStatus Failed");
    }
  }
  callbackend.open("POST", "/api/ShotStatus", true);
  let selectedCamera: string | null = GetSelectCamera();
  if (selectedCamera != null)
    callbackend.send(`{ "UUID" : "${selectedCamera}" }`);
}

function click_GetDeviceList() {
  let callbackend = new XMLHttpRequest();
  callbackend.onreadystatechange = () => {
    if (callbackend.readyState == 4) {
      if (callbackend.status == 200) {
        let rawList: string = callbackend.responseText;
        let cameraList: string[] = JSON.parse(rawList);

        let CameraNum = document.getElementById("labCameraNum");
        if (CameraNum != null)
          CameraNum.innerText = cameraList.length.toString();
        let ListHtml: string = "";
        let selectHtml: string = "";
        cameraList.forEach(item => {
          ListHtml += "<tr><th>" + item + "</th></tr>";
          selectHtml += `<option value="${item}">${item}</option>`
        });
        let ui_CameraList = document.getElementById("listCamera");
        if (ui_CameraList != null)
          ui_CameraList.innerHTML = ListHtml;
        let ui_selectList = document.getElementById("selectCamera");
        if (ui_selectList != null)
          ui_selectList.innerHTML = selectHtml;
      }
      else {
        SetLog("Call GetDeviceList Failed");
      }
    }
  }
  callbackend.open("POST", "/api/GetDeviceList", true);
  callbackend.send();
}

function click_StartShot() {
  let selectUUID = GetSelectCamera();
  if (selectUUID == null) {
    SetLog("Please select a camera");
    return;
  }
  let callbackend: XMLHttpRequest = new XMLHttpRequest();
  callbackend.onreadystatechange = () => {
    if (callbackend.readyState == 4) {
      if (callbackend.status == 200) {
        click_RefreshShotStatus();
      }
      else
        SetLog("Call StartShot Failed");
    }
  };
  callbackend.open("POST", "/api/StartShot", true);
  callbackend.send(`{"UUID" : "${selectUUID}"}`);
}

function click_StopShot() {
  let selectUUID = GetSelectCamera();
  if (selectUUID == null) {
    SetLog("Please select a camera");
    return;
  }
  let callbackend: XMLHttpRequest = new XMLHttpRequest();
  callbackend.onreadystatechange = () => {
    if (callbackend.readyState == 4) {
      if (callbackend.status == 200) {
        click_RefreshShotStatus();
      }
      else
        SetLog("Call StopShot Failed");
    }
  };
  callbackend.open("POST", "/api/StopShot", true);
  callbackend.send(`{"UUID" : "${selectUUID}"}`);
}

interface SettingItemRange {
  max: Number;
  min: Number;
}

interface SettingItemDescript {
  name: string;
  range: SettingItemRange;
  strlen: Number;
  obj: string[];
}

interface SettingItem {
  id: Number;
  readonly: Boolean;
  type: number;
  desc: SettingItemDescript;
}

let CurrentCameraSettingList: SettingItem[] = [];

function click_GetSettingList() {
  let selectUUID = GetSelectCamera();
  if (selectUUID == null) {
    SetLog("Please select a camera");
    return;
  }
  let callbackend: XMLHttpRequest = new XMLHttpRequest();
  callbackend.onreadystatechange = () => {
    if (callbackend.readyState == 4) {
      if (callbackend.status == 200) {
        ui_formSettingList.innerHTML = "";
        CurrentCameraSettingList = JSON.parse(callbackend.responseText);
        for (let i = 0; i < CurrentCameraSettingList.length; i++) {
          let item: SettingItem = CurrentCameraSettingList[i];
          let labName = document.createElement("label") as HTMLLabelElement;
          labName.innerText = item.desc.name;
          ui_formSettingList.appendChild(labName);
          switch (item.type) {
            case 0:
            case 1:
              {
                let input = document.createElement("input") as HTMLInputElement;
                input.type = "number";
                input.id = `settingItem_${item.id}`;
                input.readOnly = item.readonly.valueOf();
                input.addEventListener("change", pack_change_SettingItem(item.id.valueOf()));
                ui_formSettingList.appendChild(input);
              }
              break;
            case 2:
              {
                let input = document.createElement("input") as HTMLInputElement;
                input.type = "string";
                input.id = `settingItem_${item.id}`;
                input.readOnly = item.readonly.valueOf();
                input.addEventListener("change", pack_change_SettingItem(item.id.valueOf()));
                ui_formSettingList.appendChild(input);
              }
              break;
            case 3:
              {
                let input = document.createElement("select") as HTMLSelectElement;
                input.id = `settingItem_${item.id}`;
                for (let j = 0; j < item.desc.obj.length; j++) {
                  let selectItem = document.createElement("option") as HTMLOptionElement;
                  selectItem.value = j.toString();
                  selectItem.text = item.desc.obj[j];
                  input.appendChild(selectItem);
                }
                input.addEventListener("change", pack_change_SettingItem(item.id.valueOf()));
                ui_formSettingList.appendChild(input);
              }
              break;
            case 4:
              {
                let input = document.createElement("select") as HTMLSelectElement;
                input.id = `settingItem_${item.id}`;
                let selectItem = document.createElement("option") as HTMLOptionElement;
                selectItem.value = "1";
                selectItem.text = "True";
                input.appendChild(selectItem);
                selectItem.value = "0";
                selectItem.text = "False";
                input.appendChild(selectItem);
                input.addEventListener("change", pack_change_SettingItem(item.id.valueOf()));
                ui_formSettingList.appendChild(input);
              }
              break;
          }
          ui_formSettingList.appendChild(document.createElement("br"));
        }
      }
      else
        SetLog("Call GetSettingList Failed");
    }
  };
  callbackend.open("POST", "/api/GetSettingList", true);
  callbackend.send(`{"UUID" : "${selectUUID}"}`);
}

function GetSettingItem(uuid: string, index: number): number | string | boolean | null {
  interface settingItemValue {
    type: number;
    value: any;
  };
  let callbackend = new XMLHttpRequest();
  let retVal: any;
  callbackend.onreadystatechange = () => {
    if (callbackend.readyState == 4) {
      if (callbackend.status == 200) {
        let res: settingItemValue = JSON.parse(callbackend.responseText);
        retVal = res.value;
      }
      else retVal = null;
    }
  };
  callbackend.open("POST", "/api/GetSettingValue", false);
  let settingItemObj: { UUID: string, ID: number } = { UUID: uuid, ID: index };
  callbackend.send(JSON.stringify(settingItemObj));
  return retVal;
}

function SetSettingItem(uuid: string, index: number, value: number | string | boolean) {
  let Type: number;
  let Value: number | string | boolean;
  Type = CurrentCameraSettingList[index].type;
  switch (Type) {
    case 0:
    case 3:
      if (typeof value == "number")
        Value = Math.round(value) as number;
      else SetLog("call SetSettingItem value type not corrent");
      break;
    case 1:
      if (typeof value == "number")
        Value = value as number;
      else SetLog("call SetSettingItem value type not corrent");
    case 2:
      if (typeof value == "string")
        Value = value as string;
      else SetLog("call SetSettingItem value type not corrent");
      break;
    case 4:
      if (typeof value == "boolean")
        Value = value as boolean;
      else SetLog("call SetSettingItem value type not corrent");
      break;
  }

  class setSettingItem {
    UUID: string = uuid;
    id: number = index;
    type: bigint = BigInt(Type);
    value: number | string | boolean;
  };

  let callbackend = new XMLHttpRequest();
  callbackend.onreadystatechange = () => {
    if (callbackend.readyState == 4) {
      if (callbackend.status != 200) {
        SetLog("call SetSettingItem Failed");
      }
    }
  };
  callbackend.open("POST", "/api/SetSettingValue", false);
  callbackend.send(JSON.stringify(setSettingItem));
}

function change_SettingItem(index: number) {
  let val: string = "";
  switch (CurrentCameraSettingList[index].type) {
    case 0:
      {
        let item = document.getElementById(`settingItem_${index}`) as HTMLInputElement;
        val = Math.round(item.valueAsNumber).toString();
      }
      break;
    case 1:
      {
        let item = document.getElementById(`settingItem_${index}`) as HTMLInputElement;
        val = item.valueAsNumber.toString();
      }
      break;
    case 2:
      {
        let item = document.getElementById(`settingItem_${index}`) as HTMLInputElement;
        val = item.value;
      }
      break;
    case 3:
      {
        let item = document.getElementById(`settingItem_${index}`) as HTMLSelectElement;
        val = item.value;
      }
      break;
    case 4:
      {
        let item = document.getElementById(`settingItem_${index}`) as HTMLSelectElement;
        if (Number(item.value) == 1)
          val = "True";
        else
          val = "False";
      }
      break;
  }
  console.log(`Setting Item Finish: ${index} ${val}`);
}

function pack_change_SettingItem(index: number) {
  return function () { change_SettingItem(index); };
}

function click_GetSettingValue() {
  let currentCamera = GetSelectCamera();
  CurrentCameraSettingList.forEach(item => {
    let value = GetSettingItem(currentCamera, item.id.valueOf());
    switch (item.type) {
      case 0:
      case 1:
        {
          let uiObj = document.getElementById(`settingItem_${item.id}`) as HTMLInputElement;
          if (typeof value == "number")
            uiObj.valueAsNumber = value;
        }
        break;
      case 2:
        {
          let uiObj = document.getElementById(`settingItem_${item.id}`) as HTMLInputElement;
          if (typeof value == "string")
            uiObj.value = value;
        }
        break;
      case 3:
        {
          let uiObj = document.getElementById(`settingItem_${item.id}`) as HTMLSelectElement;
          if (typeof value == "number")
            uiObj.selectedIndex = value;
        }
        break;
      case 4:
        {
          let uiObj = document.getElementById(`settingItem_${item.id}`) as HTMLSelectElement;
          if (typeof value == "boolean")
            uiObj.selectedIndex = value ? 1 : 0;
        }
        break;
    }
  });
}

